home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / shells / guest-0.000 / guest-0 / guest-0.2 / screen.c < prev    next >
C/C++ Source or Header  |  1995-05-08  |  5KB  |  239 lines

  1. /*
  2. Displays menu and takes input
  3. Copyright (C) 1995  Brian Cully
  4.  
  5. This program is free software; you can redistribute it and/or modify it under
  6. the terms of the GNU General Public License as published by the Free Software
  7. Foundation; either version 2 of the License, or (at your option) any later
  8. version.
  9.  
  10. This program is distributed in the hope that it will be useful, but WITHOUT
  11. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  13. details.
  14.  
  15. You should have received a copy of the GNU General Public License along with
  16. this program; if not, write to the Free Software Foundation, Inc., 675 Mass
  17. Ave, Cambridge, MA 02139, USA.
  18.  
  19. please send patches (w/ explanation) or advice to: `shmit@meathook.intac.com'
  20. */
  21.  
  22. #include <ncurses/ncurses.h>
  23. #include <string.h>
  24. #include <stdio.h>
  25.  
  26. #include "screen.h"
  27. #include "misc.h"
  28.  
  29. /* Length of NOP bar */
  30. #define NOP_LINE_S 25
  31.  
  32. /* Output a menu item to the screen
  33.    src == menu item to display
  34.    attr == attribute */
  35. static void display_items(struct menu_items src, int attr) {
  36.    switch (src.type) {
  37.    case MENU_TITLE:
  38.       attrset(A_NORMAL);
  39.       addch('[');
  40.       attrset(attr);
  41.       addstr(src.name);
  42.       attrset(A_NORMAL);
  43.       addch(']');
  44.       break;
  45.    case MENU_SUB:
  46.       attrset(A_NORMAL);
  47.       addch('<');
  48.       attrset(attr);
  49.       addstr(src.name);
  50.       attrset(A_NORMAL);
  51.       addstr(">");
  52.       break;
  53.    case MENU_NOP:
  54.       attrset(A_NORMAL);
  55.       if (strlen(src.name) > 1) {
  56.      addstr(src.name);
  57.       } else {
  58.      int x, y;
  59.  
  60.      hline(ACS_HLINE, NOP_LINE_S);
  61.      getyx(stdscr, y, x);
  62.      move(y, NOP_LINE_S);
  63.       }
  64.       break;
  65.    case MENU_EXEC:
  66.       attrset(attr);
  67.       addstr(src.name);
  68.       break;
  69.    case MENU_EXIT:
  70.       attrset(attr);
  71.       addstr(src.name);
  72.       break;
  73.    }
  74.  
  75.    addstr("\n");
  76. }
  77.  
  78. /* Go down at least one row, skipping comments (MENU_NOP) and titles (MENU_TITLE)
  79.    *row == a pointer to the current row
  80.    **p == menu item list to sort through and display */
  81. static void down_hilite(int *row, struct menu_items **p) {
  82.    int back_row = *row;
  83.    struct menu_items *back_item = *p;
  84.    bool quit=FALSE;
  85.    
  86.    move(*row, 0);
  87.    display_items(**p, A_BOLD);
  88.  
  89.    while ((*p)->next && !quit) {
  90.       *p = (*p)->next; (*row)++;
  91.       switch ((*p)->type) {
  92.       case MENU_TITLE:
  93.       case MENU_NOP:
  94.      break;
  95.       default:
  96.      quit = TRUE;
  97.      break;
  98.       }
  99.    }
  100.  
  101.    if (!quit) {
  102.       *row = back_row;
  103.       *p = back_item;
  104.    }
  105.  
  106.    move(*row, 0);
  107.    display_items(**p, A_REVERSE);
  108. }
  109.  
  110. /* see down_hilite and reverse the direction */
  111. static void up_hilite(int *row, struct menu_items **p) {
  112.    int back_row = *row;
  113.    struct menu_items *back_item = *p;
  114.    bool quit=FALSE;
  115.    
  116.    move(*row, 0);
  117.    display_items(**p, A_BOLD);
  118.  
  119.    while ((*p)->prev && !quit) {
  120.       *p = (*p)->prev; (*row)--;
  121.       switch ((*p)->type) {
  122.       case MENU_TITLE:
  123.       case MENU_NOP:
  124.      break;
  125.       default:
  126.      quit = TRUE;
  127.      break;
  128.       }
  129.    }
  130.  
  131.    if (!quit) {
  132.       *row = back_row;
  133.       *p = back_item;
  134.    }
  135.  
  136.    move(*row, 0);
  137.    display_items(**p, A_REVERSE);
  138. }
  139.  
  140. /* display the menu list on the screen
  141.    **p == menu list to display
  142.    *row == pointer to current row */
  143. static void init_list(struct menu_items **p, int *row) {
  144.    struct menu_items *q = *p;
  145.    
  146.    attrset(A_NORMAL);
  147.    erase();
  148.  
  149.    while (q->prev)
  150.       q = q->prev;
  151.    
  152.    while (q) {
  153.       display_items(*q, A_BOLD);
  154.       q = q->next;
  155.    }
  156.  
  157.    if (((*p)->type == MENU_TITLE) || ((*p)->type == MENU_NOP))
  158.       down_hilite(row, p);
  159.    else {
  160.       move(*row, 0);
  161.       display_items(**p, A_REVERSE);
  162.    }
  163.  
  164.    refresh();
  165. }
  166.  
  167. /* Interface to main module
  168.    Initialize the screen, must be called before anything else */
  169. void init_scr() {
  170.    initscr();
  171.    cbreak();
  172.    noecho();
  173.    keypad(stdscr, TRUE);
  174. }
  175.  
  176. /* Interface to main module
  177.    Close the output, must be called when finished */
  178. void close_scr() {
  179.    endwin();
  180. }
  181.  
  182. void write_str(char *s) {
  183.    int row, col;
  184.  
  185.    getyx(stdscr, row, col);
  186.    mvaddstr(row, col, s);
  187.    refresh();
  188. }
  189.  
  190. void clear_scr() {
  191.    attrset(A_NORMAL); erase(); refresh();
  192. }
  193.  
  194. int readchar() {
  195.    return getch();
  196. }
  197.  
  198. /* Interface to main module
  199.    Display menu list,
  200.    *menu_list == menu list to display */
  201. void display_list(struct menu *menu_list) {
  202.    bool quit = FALSE;
  203.    struct menu_items *p = menu_list->data;
  204.    int row=0;
  205.  
  206.    if (menu_list != NULL) {
  207.       init_list(&p, &row);
  208.  
  209.       while (!quit) {
  210.      switch (getch()) {
  211.      case KEY_LEFT:
  212.         quit = TRUE;
  213.         break;
  214.  
  215.      case KEY_RIGHT:
  216.         switch (p->type) {
  217.         case MENU_EXIT:
  218.            quit = TRUE;
  219.            break;
  220.  
  221.         default:
  222.            exec_item(*p, &menu_list);
  223.            init_list(&p, &row);
  224.            break;
  225.         }
  226.         break;
  227.  
  228.      case KEY_DOWN:
  229.         down_hilite(&row, &p);
  230.         break;
  231.  
  232.      case KEY_UP:
  233.         up_hilite(&row, &p);
  234.         break;
  235.      }
  236.       }
  237.    }
  238. }
  239.